#include "SSB_uart_data_buffer.h"
#include "OPCOL_util.h"
#include "SSB_sys_def.h"

#include <string.h>
#include <stdlib.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"

#include "esp_log.h"

char *ssb_uart_buffer=NULL;
char *ssb_uart_swap_buffer=NULL;
int ssb_uart_buffer_max_len=1024*2; //2k
int ssb_uart_buffer_lock=0;
int ssb_uart_buffer_current_len=0;
int ssb_uart_data_change=0;
ON_UART_Command on_uart_cmd_cf=NULL;
SSB_Parse_buffer SSB_buffer_parser=NULL;

int SSB_buffer_default_parser(char *buf,int len,int *piece_start_index){
    extern char UART1_DATA_HEAD_MARK[8];
    extern char UART1_DATA_END_MARK[8]; 
    extern int UART1_DATA_CRC_TYPE;
    extern int UART1_DATA_CRC_LEN;
    // if(strlen(UART1_DATA_HEAD_MARK)<1){
    //     *piece_start_index=0;
    //     return len;
    // }

    return OPCOL_data_piece_pop(buf,
            len,piece_start_index,
            UART1_DATA_CRC_LEN,UART1_DATA_CRC_TYPE,
            UART1_DATA_HEAD_MARK,UART1_DATA_END_MARK);
}

int swap_buffer_data(int start_index){
    int tmp_len =ssb_uart_buffer_current_len-start_index;
    if(tmp_len<0){
        tmp_len=0;
        return 0;
    }
    memcpy(ssb_uart_swap_buffer, ssb_uart_buffer+start_index,tmp_len);
    memcpy(ssb_uart_buffer,ssb_uart_swap_buffer,tmp_len);
    return tmp_len;
}

void SSB_uart_parse_task(){
    char *uart_command=(char *)malloc(SSB_UART_CMD_MAX_LEN);
    int piece_len=0;
    int piece_start_index=0;
    while(1){
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        if(ssb_uart_data_change==0){
            continue;
        }
        
        while((piece_len=SSB_buffer_parser(ssb_uart_buffer,ssb_uart_buffer_current_len,&piece_start_index))>0){
            memcpy(uart_command,ssb_uart_buffer+piece_start_index,piece_len);
            while(ssb_uart_buffer_lock==1){
                vTaskDelay(20 / portTICK_PERIOD_MS);
            }
            ssb_uart_buffer_lock=1;
            ssb_uart_buffer_current_len=swap_buffer_data(piece_start_index+piece_len);
            
            ssb_uart_buffer_lock=0;
            if(on_uart_cmd_cf!=NULL){
                on_uart_cmd_cf(uart_command,piece_len);
            }
            if(ssb_uart_buffer_current_len<1){
                break;
            }
        }

        if(piece_len<0){
            //缓冲区里数据错位
            ssb_uart_buffer_current_len=0;
        }
        ssb_uart_data_change=0;
    }
    //free(uart_command);
}


void SSB_uart_buffer_put(char *data,int len){
    if(on_uart_cmd_cf==NULL){
        return;
    }
    
    if(len>ssb_uart_buffer_max_len){
        return;
    }
    if(len<1){
        return;
    }

    if(ssb_uart_buffer_current_len+len>ssb_uart_buffer_max_len){
        ssb_uart_buffer_current_len=0;
    }
    
    while(ssb_uart_buffer_lock==1){
        vTaskDelay(20 / portTICK_PERIOD_MS);
    }
    ssb_uart_buffer_lock=1;
    memcpy(ssb_uart_buffer+ssb_uart_buffer_current_len,data,len);
    ssb_uart_buffer_current_len=ssb_uart_buffer_current_len+len;
    ssb_uart_data_change=1;
    ssb_uart_buffer_lock=0;
    
}


void SSB_init_uart_buffer(ON_UART_Command cf,SSB_Parse_buffer parser){
    ssb_uart_buffer_lock=0;
    ssb_uart_buffer=(char *)malloc(ssb_uart_buffer_max_len);
    ssb_uart_swap_buffer=(char *)malloc(ssb_uart_buffer_max_len);
    on_uart_cmd_cf=cf;
    if(parser==NULL){
        SSB_buffer_parser=SSB_buffer_default_parser;
    }else
    {
        SSB_buffer_parser=parser;
    }
    
    xTaskCreate(SSB_uart_parse_task,
                      "SSB_uart_parse_task",
                      1024*6,
                      NULL,
                      8,
                      NULL);
}
